package com.zrrd.yunchmall.gateway.filter;
import com.zrrd.yunchmall.gateway.client.AuthServiceClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.List;
/**
 * 在网关中实现统一的权限认证
 * 针对每个请求头或请求参数中的token令牌进行有效性验证，如果有效就完成后续的路由操作，否则就返回401错误（无访问权限）
 */
//第一步，声明一个Filter类，实现GlobalFilter接口
    @Service//第三步，将这个类注入Spring的bean容器
    @ConfigurationProperties("auth-filter")
public class AuthGlobalFilter implements GlobalFilter, Ordered {
    @Override
    public int getOrder(){
        return 1;
    }
        //不需要进行鉴权的请求路径集合（excludes包括的路径直接放行）
        private List<String> excludes;

    public List<String> getExcludes() {
        return excludes;
    }
    public void setExcludes(List<String>excludes){
        this.excludes=excludes;
    }
@Autowired
private AuthServiceClient authService;
    private boolean enabled;
    //配置一个基于配置文件的开关，true 过滤器工作
    @Override
    //第二步，重写filter方法
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
       //请求路径/shop-user/user/login
        if (!enabled) {
            return chain.filter(exchange);
        }
        String uri = exchange.getRequest().getURI().getPath();
        if (excludes.contains(uri))
        {
           return chain.filter(exchange);
        }
        //Authorization这个请求头要包含jwt token
        String token = exchange.getRequest().getHeaders().getFirst("Authorization");
      //1没找到token 2.token过期了3.token无效
       if (token==null || authService.auth(token)==null ){
        exchange.getResponse().setStatusCode(HttpStatus.ALREADY_REPORTED);
        return exchange.getResponse().setComplete();//响应结束，方法终止
       }else {
            return chain.filter(exchange);
       }
    }
}
